package com.donger.mes.system.mes.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.donger.mes.system.mes.dto.WorkCenterMatPlatformDTO;
import com.donger.mes.system.mes.entity.WorkCenterMat;
import com.donger.mes.system.mes.mapper.WorkCenterMatMapper;
import com.donger.mes.system.mes.service.WorkCenterMatService;
import com.donger.mes.system.side.entity.MesSideWarehouse;
import com.donger.mes.system.side.service.MesSideWarehouseService;
import lombok.AllArgsConstructor;
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;

/**
 * 工作中心物料查询
 */
@Service
@AllArgsConstructor
public class WorkCenterMatServiceImpl implements WorkCenterMatService {
    private final WorkCenterMatMapper workCenterMatMapper;
    private final MesSideWarehouseService mesSideWarehouseService;

    @Override
    public IPage<WorkCenterMat> page(IPage<WorkCenterMat> page, Wrapper<WorkCenterMat> queryWrapper) {
        return workCenterMatMapper.selectPage(page, queryWrapper);
    }

    /**
     * 获取对应工单各种物料的剩余数量
     *
     * @param planCode
     */
    @Override
    public List<WorkCenterMatPlatformDTO> listGroupByWorkCenter(String planCode) {
        List<Map<String, Object>> maps = workCenterMatMapper.selectMaps(Wrappers.<WorkCenterMat>query()
                .select("sum(current_number) as num,mat_code,mat_name")
                .lambda()
                .eq(WorkCenterMat::getPlanCode, planCode)
                .groupBy(WorkCenterMat::getMatCode)
        );

        List<WorkCenterMatPlatformDTO> collect = maps.stream().map(item -> {
            WorkCenterMatPlatformDTO workCenterMatPlatFormDTO = BeanUtil.copyProperties(item, WorkCenterMatPlatformDTO.class);
            return workCenterMatPlatFormDTO;
        }).collect(Collectors.toList());

        return collect;

    }

    /**
     * 新增或者更新物料信息
     * @param workCenterMat
     * @return
     */
    @Override
    public Boolean save(WorkCenterMat workCenterMat) {
        int flag = 0;
        if(workCenterMat.getId()!= null){
            flag = workCenterMatMapper.updateById(workCenterMat);
        }else{
            flag = workCenterMatMapper.insert(workCenterMat);
        }
        return flag == 1;
    }

    /**
     * 查询当前工作重心物料中唯一标志的物料信息
     * @param workCenterCode
     * @param packageCode
     * @param supplier
     * @return
     */
    @Override
    public WorkCenterMat queryByBarcodeAndSupplier(String workCenterCode,String packageCode, String supplier,String planCode) {
        return workCenterMatMapper.selectOne(Wrappers.<WorkCenterMat>lambdaQuery()
                .eq(WorkCenterMat::getMatBarcode, packageCode)
                .eq(WorkCenterMat::getSupplierCode, supplier)
                .eq(WorkCenterMat::getWorkCenterCode,workCenterCode)
                .eq(WorkCenterMat::getPlanCode,planCode)
        );
    }

    @Override
    public List<WorkCenterMat> list(Wrapper<WorkCenterMat> queryWrapper) {
        return workCenterMatMapper.selectList(queryWrapper);
    }

    @Override
    @Transactional
    public void updateBatchById(List<WorkCenterMat> updateMatList) {
        if(CollUtil.isEmpty(updateMatList)){
            return;
        }
        String sqlStatement = SqlHelper.getSqlStatement(WorkCenterMatMapper.class, SqlMethod.UPDATE_BY_ID);
        this.executeBatch(updateMatList, 1000, (sqlSession, entity) -> {
            MapperMethod.ParamMap<WorkCenterMat> param = new MapperMethod.ParamMap();
            param.put("et", entity);
            sqlSession.update(sqlStatement, param);
        });
    }

    protected <E> boolean executeBatch(Collection<WorkCenterMat> list, int batchSize, BiConsumer<SqlSession, WorkCenterMat> consumer) {
        return SqlHelper.executeBatch(WorkCenterMat.class, null, list, batchSize, consumer);
    }

    @Override
    public void deleteBatchById(List<WorkCenterMat> deleteMatList) {
        if(CollUtil.isEmpty(deleteMatList)){
            return;
        }
        workCenterMatMapper.deleteBatchIds(deleteMatList.stream().map(WorkCenterMat::getId).collect(Collectors.toList()));
    }

    /**
     * 工作中心退料到线边库
     * @param workCenterCode
     * @param planCode
     */
    @Override
    @Transactional
    public void returnMaterial(String workCenterCode,String planCode) {

        List<WorkCenterMat> workCenterMats = workCenterMatMapper.selectList(Wrappers.<WorkCenterMat>lambdaQuery()
                .eq(WorkCenterMat::getPlanCode, planCode)
                .gt(WorkCenterMat::getCurrentNumber, 0)
        );

        // 循环退回
        for (WorkCenterMat item: workCenterMats){
            MesSideWarehouse mesSideWarehouse = new MesSideWarehouse();
            mesSideWarehouse.setCurrentNumber(item.getCurrentNumber());
            mesSideWarehouse.setEnterTime(LocalDateTime.now());
            mesSideWarehouse.setMatBarcode(item.getMatBarcode());
            mesSideWarehouse.setMatCode(item.getMatCode());
            mesSideWarehouse.setMatName(item.getMatName());
            mesSideWarehouse.setSupplier(item.getSupplierCode());
            mesSideWarehouseService.input(mesSideWarehouse);
        }
        workCenterMatMapper.delete(Wrappers.<WorkCenterMat>lambdaQuery().eq(WorkCenterMat::getPlanCode,planCode));
    }
}
